﻿using System;
using System.Collections.Generic;
using System.Text;

using Csla;
using Csla.Data;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace buildingLib
{
    [Serializable()]
    public class Renter:BusinessBase<Renter>
    {
        #region Business Methods
        int m_id = 0;
        string m_name = string.Empty;
        bool m_gender = true;      
        string m_IDCard = string.Empty;
        string m_company = string.Empty;
        string m_tel = string.Empty;
        bool m_hasCar = false;
        string m_carowner = string.Empty;
        Guid m_doorID;
        DateTime m_startDate = DateTime.Today;
        DateTime m_endDate = DateTime.MaxValue;
        SmartDate m_smartEnd = new SmartDate(false);
        string m_memo;
        int m_renterCount = 1;


        public SmartDate SmartEnd
        {
            get { return m_smartEnd; }
        }
        public int ID
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_id;
            }
        }
        public string Memo
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_memo;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_memo != value)
                {
                    m_memo = value;
                    PropertyHasChanged();
                }
            }
        }
        public string CarOwner
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_carowner;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_carowner != value)
                {
                    m_carowner = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Name
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_name;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_name != value)
                {
                    m_name = value;
                    PropertyHasChanged();
                }
            }
        }

        public bool Gender
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_gender;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);                
                if (m_gender != value)
                {
                    m_gender = value;
                    PropertyHasChanged();
                }
            }
        }

        public bool HasCar
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_hasCar;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (m_hasCar != value)
                {
                    m_hasCar = value;
                    if (!m_hasCar)
                        this.CarOwner = string.Empty;
                    PropertyHasChanged();
                }
            }
        }

        public DateTime StartDate
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_startDate;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (m_startDate != value)
                {
                    m_startDate = value;
                    PropertyHasChanged();
                }
            }
        }

        public DateTime EndDate
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_smartEnd.Date;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (m_smartEnd != value)
                {
                    m_smartEnd = new SmartDate(value);
                    PropertyHasChanged();
                }
            }
        }

        public int RenterCount
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_renterCount;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (m_renterCount != value)
                {
                    m_renterCount = value;
                    PropertyHasChanged();
                }
            }
        }

        
        public string IDCard
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_IDCard;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_IDCard != value)
                {
                    m_IDCard = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Company
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_company;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_company != value)
                {
                    m_company = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Tel
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_tel;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_tel != value)
                {
                    m_tel = value;
                    PropertyHasChanged();
                }
            }
        }

        public Guid DoorID
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_doorID;
            }
        }


        protected override object GetIdValue()
        {
            return m_id;
        }
        #endregion
     

        #region Validation Rules

        protected override void AddBusinessRules()
        {
            ValidationRules.AddRule(
              Csla.Validation.CommonRules.StringRequired, "Name");
            ValidationRules.AddRule(
              Csla.Validation.CommonRules.StringMaxLength,
              new Csla.Validation.CommonRules.MaxLengthRuleArgs("Name", 50));

            ValidationRules.AddRule<Renter>(
              StartDateGTEndDate<Renter>, "StartDate");
            ValidationRules.AddRule<Renter>(
              StartDateGTEndDate<Renter>, "EndDate");

            ValidationRules.AddDependantProperty("StartDate", "EndDate", true);
        }

        private static bool StartDateGTEndDate<T>(
          T target, Csla.Validation.RuleArgs e) where T : Renter
        {
            if (target.m_startDate > target.m_endDate)
            {
                e.Description =
                  "开始时间晚于结束时间";
                return false;
            }
            else
                return true;
        }

        #endregion

        #region Factory Methods
        public static Renter NewRenter(Guid doorid)
        {
            return new Renter(doorid);
        }

        public static Renter GetRenter(SafeDataReader dr)
        {
            return new Renter(dr);
        }

        //private Member() { MarkAsChild(); }
        private Renter(Guid doorid)
        {
            MarkAsChild();
            m_doorID = doorid;
        }
        private Renter(SafeDataReader dr)
        {
            MarkAsChild();
            Fetch(dr);
        }
        #endregion

        #region DataAccess
        private void Fetch(SafeDataReader dr)
        {
            m_id = dr.GetInt32("id");
            m_name = dr.GetString("name");
            m_gender = dr.GetBoolean("gender");            
            m_IDCard = dr.GetString("idcard");
            m_company = dr.GetString("company");
            m_tel = dr.GetString("tel");
            m_doorID = dr.GetGuid("doorid");
            m_startDate = dr.GetDateTime("startdate");
            m_endDate = dr.GetDateTime("enddate");
            m_smartEnd = dr.GetSmartDate("enddate");
            m_renterCount = dr.GetInt32("rentercount");
            m_hasCar = dr.GetBoolean("hascar");
            m_carowner = dr.GetString("carowner");
            m_memo = dr.GetString("memo");
            MarkOld();
        }

        internal void Insert()
        {
            if (!this.IsDirty) return;
            Database db = SQLDatabase.GetDatabase();
            DbCommand dbcom = db.GetStoredProcCommand("usp_GInsertRenter");
            db.AddOutParameter(dbcom, "id", DbType.Int32, 4);
            DoInsertUpdate(dbcom);
            m_id = (int)db.GetParameterValue(dbcom, "id");
            MarkOld();
        }

        internal void Update()
        {
            if (!this.IsDirty) return;

            Database db = SQLDatabase.GetDatabase();
            DbCommand dbcom = db.GetStoredProcCommand("usp_GUpdateRenter");
            db.AddInParameter(dbcom, "id", DbType.Int32, m_id);

            DoInsertUpdate(dbcom);

            MarkOld();
        }

        private void DoInsertUpdate(DbCommand dbcom)
        {
            Database db = SQLDatabase.GetDatabase();
            db.AddInParameter(dbcom, "name", DbType.String, m_name);
            db.AddInParameter(dbcom, "gender", DbType.Boolean, m_gender);            
            db.AddInParameter(dbcom, "tel", DbType.String, m_tel);
            db.AddInParameter(dbcom, "idcard", DbType.String, m_IDCard);
            db.AddInParameter(dbcom, "company", DbType.String, m_company);
            db.AddInParameter(dbcom, "doorid", DbType.Guid, m_doorID);
            db.AddInParameter(dbcom, "startdate", DbType.DateTime, m_startDate.Date);
            db.AddInParameter(dbcom, "enddate", DbType.DateTime, m_smartEnd.DBValue);
            db.AddInParameter(dbcom, "rentercount", DbType.Int32, m_renterCount);
            db.AddInParameter(dbcom, "hascar", DbType.Boolean, m_hasCar);
            db.AddInParameter(dbcom, "carowner", DbType.String, m_carowner);
            db.AddInParameter(dbcom, "memo", DbType.String, m_memo);

            db.ExecuteNonQuery(dbcom);
        }

        internal void DeleteSelf()
        {
            // if we're not dirty then don't update the database
            if (!this.IsDirty) return;

            // if we're new then don't update the database
            if (this.IsNew) return;

            Database db = SQLDatabase.GetDatabase();
            DbCommand dbcom = db.GetStoredProcCommand("usp_GDeleteRenter");
            db.AddInParameter(dbcom, "id", DbType.Int32, m_id);

            db.ExecuteNonQuery(dbcom);

            MarkNew();
        }
        #endregion
    }
}
